//
//  DemoDateTime.swift
//  swiftDemo
//
//  Created by JIENING ZHANG on 2020/1/9.
//  Copyright © 2020 lovivid. All rights reserved.
//

import Foundation
import UIKit

class DemoDateTime: NSObject {
    class func timeStamp() {
        
        let dateNow = Date();
        
        // 日期对象--》 到时间戳
        //   秒时间戳，浮点
        let dateNowTSDoube = dateNow.timeIntervalSince1970;
        
        //   秒时间戳，长整
        let dateNowTSSeconds:Int64 = (Int64)(dateNowTSDoube);
        //   毫秒时间戳，长整
        let dateNowTSlMilliseconds:Int64 = (Int64)(dateNowTSDoube*1000);
        //   微秒时间戳，长整
        let dateNowTSMicrosecond:Int64 = (Int64)(dateNowTSDoube*1000000);
        
        print("date2ts: date\(dateNow) --> ts: \(dateNowTSDoube)");
        print("date2ts: date\(dateNow) --> ts: \(dateNowTSSeconds)(s)");
        print("date2ts: date\(dateNow) --> ts: \(dateNowTSlMilliseconds)(ms)");
        print("date2ts: date\(dateNow) --> ts: \(dateNowTSMicrosecond)(μs)");
        
        // 昨日此秒
        let yesterdayTSDouble =  dateNowTSDoube - 86400.0;
        let yesterdayTSSeconds:Int64 =          (Int64)(yesterdayTSDouble);
        let yesterdayTSlMilliseconds:Int64 =    (Int64)(yesterdayTSDouble*1000);
        let yesterdayTSMicrosecond:Int64 =      (Int64)(yesterdayTSDouble*1000000);
        
        // 时间戳--》日期对象
        let dateYesterday = Date.init(timeIntervalSince1970:yesterdayTSDouble);
        
        print("date2ts: date\(dateYesterday) --> ts: \(yesterdayTSDouble)");
        print("date2ts: date\(dateYesterday) --> ts: \(yesterdayTSSeconds)(s)");
        print("date2ts: date\(dateYesterday) --> ts: \(yesterdayTSlMilliseconds)(ms)");
        print("date2ts: date\(dateYesterday) --> ts: \(yesterdayTSMicrosecond)(μs)");
        
        // 字符串到日期对象
        let df = DateFormatter()
        df.dateFormat = "yyyy-MM-dd HH:mm:ss";
        
        let dateStr1 = "2019-05-05 23:32:59";
        let date1 : Date? = df.date(from: dateStr1);
        let date1TS = date1?.timeIntervalSince1970;
        print("date1 from \(dateStr1) --> "+"\( date1 != nil ? date1!.description : "invalidDate") "+" ts: \(date1TS ?? 0)");
        
        let dateStr2 = "2020-02-30 23:32:59";
        let date2 : Date? = df.date(from: dateStr2);
        let date2TS = date2?.timeIntervalSince1970;
        print("date1 from \(dateStr2) --> "+"\( date2 != nil ? date2!.description : "invalidDate") "+" ts: \(date2TS ?? 0)");
        
        // 日期对象到字符串
        print("dateNow format:\(df.string(from: dateNow))");
    }
    
    class func demoLogic() {
        // 计算耗时单位毫秒
        let start:CFAbsoluteTime = CFAbsoluteTimeGetCurrent();

        timeStamp()

        let end:CFAbsoluteTime = CFAbsoluteTimeGetCurrent();

        print("time cost : \(end - start)(ms) ");
/*
输出:

date2ts: date2020-01-09 02:30:18 +0000 --> ts: 1578537018.544118
date2ts: date2020-01-09 02:30:18 +0000 --> ts: 1578537018(s)
date2ts: date2020-01-09 02:30:18 +0000 --> ts: 1578537018544(ms)
date2ts: date2020-01-09 02:30:18 +0000 --> ts: 1578537018544118(μs)
date2ts: date2020-01-08 02:30:18 +0000 --> ts: 1578450618.544118
date2ts: date2020-01-08 02:30:18 +0000 --> ts: 1578450618(s)
date2ts: date2020-01-08 02:30:18 +0000 --> ts: 1578450618544(ms)
date2ts: date2020-01-08 02:30:18 +0000 --> ts: 1578450618544118(μs)
date1 from 2019-05-05 23:32:59 --> 2019-05-05 15:32:59 +0000  ts: 1557070379.0
date1 from 2020-02-30 23:32:59 --> invalidDate  ts: 0.0
time cost : 0.005066990852355957(ms)
*/
    }
    
    static var machTimeInfo:mach_timebase_info_data_t = mach_timebase_info_data_t();
    static var logTsBase:UInt64 = 0;
    
//    @objc class func swiftLoad() {
//        // do something
//        print("DemoDateTime swiftLoad")
//        mach_timebase_info(&machTimeInfo);
//        logTsBase = mach_absolute_time();
//    }
    
    class func logTsBegin(_ info:String) {
        if 0 == machTimeInfo.denom {
            mach_timebase_info(&machTimeInfo);
        }
        logTsBase = mach_absolute_time();
        print("0, \(info)");
    }
    
    class func logTs(_ info:String, _ durationScale:String = "us", _ showThread:Bool=false) {
        //let logTsNow = mach_absolute_time();
        let elapsed = mach_absolute_time() - logTsBase;
            
        let nanos = elapsed * UInt64(machTimeInfo.numer) / UInt64(machTimeInfo.denom);
        var threadInfo = "";
        if showThread {
            threadInfo = Thread.isMainThread ? "mt, ":"gt, ";
        }
        switch (durationScale) {
        case "us":
            print("\(nanos/1000)us, \(threadInfo)\(info)");
        case "ms":
            print("\(nanos/1000000)ms, \(threadInfo)\(info)");
        case "ns":
            print("\(nanos)ns, \(threadInfo)\(info)");
        case "s":
            print("\(nanos/1000000000)ns, \(threadInfo)\(info)");
        default:
            print("\(nanos/1000)us, \(threadInfo)\(info)");
        }
    }
}
